#include "HelloWorldScene.h"

USING_NS_CC;

//#define GATE_HOST "114.113.202.141"
//#define GATE_PORT 3088
#define GATE_HOST "192.168.1.108"
#define GATE_PORT 3014

static const char* connectorHost = "";
static int connectorPort = 0;
static std::string username = "";
static std::string channel = "";
static pc_client_t* pomelo_client = NULL;
static __Array* messageQueue = NULL;
static __Array* userQueue = NULL;
static int error = 0;
static json_t* userList = NULL;

static void on_close(pc_client_t *client, const char *event, void *data);

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();
    
    // add layer as a child to scene
    scene->addChild(layer);
    
    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init() {
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() ){
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.
    
    auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::doLogin, this) );
    
	closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));
    
    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
    
    return true;
}

void HelloWorld::requstGateCallback(pc_request_t *req, int status, json_t *resp)
{
    log("requstGateCallback");
    if(status == -1) {
        log("Fail to send request to server.\n");
    } else if(status == 0) {
        connectorHost = json_string_value(json_object_get(resp, "host"));
        connectorPort = json_number_value(json_object_get(resp, "port"));
        log("connectorHost=%s connectorPort=%d", connectorHost,connectorPort);
        pc_client_t *client = pc_client_new();
        
        struct sockaddr_in address;
        
        memset(&address, 0, sizeof(struct sockaddr_in));
        address.sin_family = AF_INET;
        address.sin_port = htons(connectorPort);
        address.sin_addr.s_addr = inet_addr(connectorHost);
        
        //        // add pomelo events listener
        //        void (*on_disconnect)(pc_client_t *client, const char *event, void *data) = &HelloWorld::onDisconnectCallback;
        //        void (*on_chat)(pc_client_t *client, const char *event, void *data) = &HelloWorld::onChatCallback;
        //        void (*on_add)(pc_client_t *client, const char *event, void *data) = &HelloWorld::onAddCallback;
        //        void (*on_leave)(pc_client_t *client, const char *event, void *data) = &HelloWorld::onLeaveCallback;
        //
        //        pc_add_listener(client, "disconnect", on_disconnect);
        //        pc_add_listener(client, "onChat", on_chat);
        //        pc_add_listener(client, "onAdd", on_add);
        //        pc_add_listener(client, "onLeave", on_leave);
        
        // try to connect to server.
        if(pc_client_connect(client, &address)) {
            log("fail to connect server.\n");
            pc_client_destroy(client);
            return ;
        }
        
        const char *route = "connector.entryHandler.login";
        json_t *msg = json_object();
        username = "10000000";
        json_t *str = json_string(username.c_str());
//        json_t *channel_str = json_string(channel.c_str());
        json_object_set(msg, "uid", str);
//        json_object_set(msg, "rid", channel_str);
        // decref for json object
        json_decref(str);
//        json_decref(channel_str);
        
        //        pc_request_t *request = pc_request_new();
        //        void (*connect_cb)(pc_request_t *req, int status, json_t *resp )= &HelloWorld::requstConnectorCallback;
        //        pc_request(client, request, route, msg, connect_cb);
		
		/*
         char *json_str = json_dumps(resp, 0);
         if(json_str != NULL) {
         log("server response: %s %d\n", connectorHost, connectorPort);
         free(json_str);
         }
         */
    }
    
    // release relative resource with pc_request_t
    json_t *pc_msg = req->msg;
    pc_client_t *pc_client = req->client;
    json_decref(pc_msg);
    pc_request_destroy(req);
    
    pc_client_stop(pc_client);
}

void HelloWorld::doLogin(Ref* sender)
{
    log("doLogin");
    const char *ip = GATE_HOST;
    int port = GATE_PORT;
    
    pc_client_t *client = pc_client_new();
    
    struct sockaddr_in address;
    
    memset(&address, 0, sizeof(struct sockaddr_in));
    address.sin_family = AF_INET;
    address.sin_port = htons(port);
    address.sin_addr.s_addr = inet_addr(ip);
    
    //try to connect to server.
    if(pc_client_connect(client, &address)) {
        log("fail to connect server.\n");
        pc_client_destroy(client);
        return ;
    }
    
    //add some event callback.
    //pc_add_listener(client, PC_EVENT_DISCONNECT, on_close);
    
    const char *route = "gate.gateHandler.queryEntry";
    json_t *msg = json_object();
    username = "10000000";
    json_t *str = json_string(username.c_str());
    //        json_t *channel_str = json_string(channel.c_str());
    json_object_set(msg, "uid", str);
//    json_t *str = json_string(username.c_str());
//    json_object_set(msg, "uid", str);
//    //decref for json object
//    json_decref(str);
    
    pc_request_t *request = pc_request_new();
    void (*on_request_gate_cb)(pc_request_t *req, int status, json_t *resp) = &HelloWorld::requstGateCallback;
    pc_request(client, request, route, msg, on_request_gate_cb);
    
    //main thread has nothing to do and wait until child thread return.
    pc_client_join(client);
    
    //release the client
    pc_client_destroy(client);
}



